//////////////////////////////////////////////////////////////////////////
// PeekPocket - the hassle-free WiFi scanner for Windows Mobile
// coded by dzolee
// http://dzolee.blogspot.com
//
// Data storage - provides access to AP scan data. Contains items indexed
// by both MAC address and ID.
//////////////////////////////////////////////////////////////////////////

#pragma once

#include <afxwin.h>
#include "PeekPocket.h"
#include "WifiPeek.h"

//////////////////////////////////////////////////////////////////////////
struct DisplayInfo : BSSIDInfo
{
	DWORD ID;
	bool bActive;
	DATE dFirstSeen;
	DATE dLastSeen;
	int iBestSig;
	int iWorstSig;
};

//map by MAC address
typedef CMap<BYTE *, BYTE *, DisplayInfo *, DisplayInfo *> DisplayInfoMACMap;

//mac by ID
typedef CMap<DWORD, DWORD, DisplayInfo *, DisplayInfo *> DisplayInfoIDMap;

//array of structs - required while population list control
typedef CArray<DisplayInfo *> DisplayInfoArray;

//////////////////////////////////////////////////////////////////////////
//MAC Address hashing - used by map container
template<>
AFX_INLINE UINT AFXAPI HashKey<BYTE *> (BYTE *pKey)
{
	int i;
	UINT nHash;

	nHash = 0;
	for(i=0; i<6; i++)
	{
		nHash = (nHash<<5) + nHash + pKey[i];
	}
	return nHash;
}

//////////////////////////////////////////////////////////////////////////
template<>
AFX_INLINE BOOL AFXAPI CompareElements<BYTE *>(BYTE * const * pElement1, BYTE * const * pElement2)
{
	ENSURE(pElement1 != NULL && pElement2 != NULL);
	//this is a dummy function, when it gets called, hashes were already checked by MFC and this just does fine
	return TRUE;
}

//////////////////////////////////////////////////////////////////////////
class CDataStorage
{
public:
	CDataStorage();
	~CDataStorage();
	
	void Clear();
	void SerializeTxt();
	void ProcessInput(struct BSSIDInfo *pInfo, DWORD dwNum);

	bool GetItemByID(DWORD dwID, DisplayInfo *pOut);
	bool GetFilteredItemByIndex(DWORD dwIdx, DisplayInfo *pOut);
	
	void GetCounts(DWORD &dwFiltered, DWORD &dwFilteredActive);

	void DeleteOldDuplicates();

private:
	CRITICAL_SECTION m_Lock;

	//maps indexed by ID/MAC
	DisplayInfoIDMap m_IDMap;
	DisplayInfoMACMap m_MACMap;

	//array preserved between GetDispInfo calls
	DisplayInfoArray m_TmpArray;
};
